/*
 * MockWritableSelectableChannel.java    0.0.1    21/set/2009
 * 
 * Copyright (c) 2009 mentalsmash.org
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * The use of the Apache License does not indicate that this project is
 * affiliated with the Apache Software Foundation.
 */ 
package org.mentalsmash.tazio.net.cs.server.impl.mock;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.SelectableChannel;
import java.nio.channels.WritableByteChannel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Implements a WritableByteChannel. The data that is written on this channel after <code>write()</code>
 * operations can be retrieved by calling
 * {@link MockWritableSelectableChannel#getWrittenData() getWrittenData() }.
 * <p>
 * This channel can be registered to a selector for readiness events.
 * </p>
 * <p>
 * Used for testing purposes
 * </p>
 * @version    0.0.1    21/set/2009    
 * @author     Andrea Reale <andrea.reale@gmail.com>
 */
public class MockWritableSelectableChannel extends MockSelectableChannel implements
		WritableByteChannel {

	private final static Logger log = LoggerFactory.getLogger(MockWritableSelectableChannel.class);
	
	private final Pipe outPipe;

	
	/**
	 * Creates a new MockWritableSelectableChannel
	 * @throws IOException if an error occurs among creation
	 */
	public MockWritableSelectableChannel() 
		throws IOException{
		
		
		outPipe = Pipe.open();
	}
	
	
	/**
	 * The end of the pipe that is being exposed to the public
	 * @return The end of the pipe that is being exposed to the public
	 */
	@Override
	protected SelectableChannel getChannel(){
		return outPipe.sink();
	}

	
	/**
	 * Retrieve the data that was previously written to this channel by <code>write()</code> calls
	 * <p>
	 * The bytes that are returned by this method are also dequeued from the channel. (so they will not be
	 * returned again in subsequent calls.
	 * </p>
	 * @return an array containing the data that was previously written to the channel
	 */
	public byte[] getWrittenData() {
		byte[] writtenData;
		ByteBuffer buff;
		
		
		writtenData = new byte[CHANNEL_SIZE];
		buff = ByteBuffer.wrap(writtenData);
		
		try {
			outPipe.source().read(buff);
		} catch (IOException e) {
			log.error("Unexpected exception",e);
			throw new RuntimeException("Unexpected exception",e);
		}
		
		return writtenData;
	}
	
	

	/* (non-Javadoc)
	 * @see java.nio.channels.spi.AbstractInterruptibleChannel#implCloseChannel()
	 */
	@Override
	protected void implCloseChannel() throws IOException {
		outPipe.sink().close();
		outPipe.source().close();

	}



	/* (non-Javadoc)
	 * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
	 */
	@Override
	public int write(ByteBuffer src) throws IOException {
		return outPipe.sink().write(src);
	}

}
